﻿package newx.com.control.Scroll
{
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import newx.StageInfo;
	import newx.com.NxUIComponent;
	import newx.com.ResManager;
	import newx.com.utils.draw.DrawStyle;
	import newx.utils.DrawAPI;

	/**
	 * note ,not code(may be a little) .
	 * 2010-11-1 Freeyouth注.
	 * if any body benefits from this note,don't thanks me.
	 * just write note when  Catching on your code difficult only by the name of variables.
	*/
	public class NxScrollBar extends NxUIComponent
	{
		
		public static var VERTICAL		:int	=	0;
		
		public static var HORIZONTAL		:int	=	1;
		
		//数据层
		/**当前滚动值[0,1]*/
		private var _value					:int	= 	0;
		
		private var _minSize				:Number	=	1;
		
		/**滑动总长度=head+snail+barSize*/
		private var _extent				:int	= 	111;
		
		/**滑块最小宽度 or 长度 ，防止太小了拖拽不方便*/
		private var _sliderMinLen		:Number=10;
		
		private var _barSize				:int 	= 	75;
		
		private var _barWidth				:int	=	16;
		
		/**每次移动的长度 */
		public var _scrollDistance		:Number	=	5;
		
		/**滑动画位置占可滑动区的百分比，这个值暂时不是实时的*/
		private var _scroll				:Number;
		
		/**方向 ，默认0 ，垂直*/
		private var _orientation			:int	=	NxScrollBar.VERTICAL;
		//数据层END
		
		//显示层
		/**背景 显示对象*/
		private var bg_space				:Sprite	=	null;
		private var track					:Sprite;
		/**头 显示对象*/
		private var first_space			:Sprite	=	null;
		/**尾部 显示对象*/
		private var last_space				:Sprite	=	null;
		/**滑块显示对象*/
		private var _barBtn					:Sprite;
		
		/**滑块皮肤显示对象，为_barBtn 的子对象*/
		private var barSkin					:MovieClip;
		
		private var hot_area				:Sprite	=	null;
		
		private var _scrollSkin			:MovieClip;
		//显示层END		

				
		public function NxScrollBar(orientation:int = 0,value:int=0, extent:int=62,barSize:int = 30,_skin:NxScrollSkin=null)
		{
			super();
			_barSize = barSize;
			_value = value;
			_extent = extent;
			_orientation = orientation;
			if(_orientation	==	NxScrollBar.VERTICAL&&_skin!=null)
				_scrollSkin	=	ResManager.newResClass(_skin.verSkin) as MovieClip;
			else if(_orientation	==	NxScrollBar.HORIZONTAL&&_skin!=null)
				_scrollSkin	=	ResManager.newResClass(_skin.horSkin) as MovieClip;
			drawScroll();
			initEvent();
			this.scroll = value;
		}
		/**
		 * 更新滚动条，根据滚动总长度和 滑块大小更新
		 * @param extent总大小 ,指滚动方向
		 * @param barSize滑块大小，滚动方向
		 * */
		public function update(extent:int=62,barSize:int = 30):void
		{
			if(barSize<_sliderMinLen)
			{
				_barSize=_sliderMinLen;
			}
			else
			{
				if(_orientation == NxScrollBar.VERTICAL)
				{
					_barSize = Math.min( barSize, track.height );
				}else
				{
					_barSize = Math.min( barSize, track.width );
				}
			
			}
			
			_extent = extent;
			setPosition();
		}
		
		private function initEvent():void
		{
			barBtn.addEventListener(MouseEvent.MOUSE_DOWN, onBarDown);
			barBtn.addEventListener(MouseEvent.MOUSE_UP, onBarUp);
			barBtn.addEventListener(MouseEvent.ROLL_OUT, onOut);
			barBtn.addEventListener(MouseEvent.ROLL_OVER, onOver);
			first_space.addEventListener(MouseEvent.MOUSE_DOWN,headMouseDownHandle);
			last_space.addEventListener(MouseEvent.MOUSE_DOWN, snailMouseDownHandle);
			addEventListener(MouseEvent.MOUSE_UP, onScrollUP);
		}
		
		private function onOut(e:MouseEvent):void
		{
			barSkin.gotoAndStop(1);
		}
		
		private function onOver(e:MouseEvent):void
		{
			barSkin.gotoAndStop(2);
		}
		
		private function onScrollUP(e:MouseEvent):void
		{
			if(null != StageInfo.stage)
			{
				StageInfo.stage.dispatchEvent(new NxScrollEvent(NxScrollEvent.ONSCROLL_UP));
			}
		}
		
		private function onBarUp(e:MouseEvent):void
		{
			barSkin.gotoAndStop( 1 );
			
			hot_area.removeEventListener(MouseEvent.ROLL_OUT,onBarUp);
			hot_area.removeEventListener(Event.ENTER_FRAME,checkBar);
			
			while(hot_area.numChildren>0)
			{
				hot_area.removeChildAt(0);
			}
			hot_area.graphics.clear();
			barBtn.stopDrag();
		}
		
		private function onBarDown(e:MouseEvent):void
		{
			barSkin.gotoAndStop( 3 );
			
			if(_orientation == NxScrollBar.VERTICAL)
			{
				barBtn.startDrag(false,new Rectangle(bg_space.x,bg_space.y,0,_extent-_barSize-_barWidth * 2));
			}
			else
			{
				barBtn.startDrag(false,new Rectangle(bg_space.x,bg_space.y,_extent-_barSize-_barWidth * 2,0));
			}
			if(_orientation == NxScrollBar.VERTICAL)
			{
				DrawAPI.drawRect(hot_area.graphics,
					DrawStyle.getRectStyle(bg_space.x-200,bg_space.y-500,bg_space.x+bg_space.width+400,bg_space.y+bg_space.height+1000),
					DrawStyle.getFillStyle(0x556B75,1)
						);
			}
			else
			{
				DrawAPI.drawRect(hot_area.graphics,
					DrawStyle.getRectStyle(bg_space.x-500,bg_space.y-200,bg_space.x+bg_space.width+1000,bg_space.y+bg_space.height+400),
					DrawStyle.getFillStyle(0x556B75,1));
			}
			
			hot_area.addEventListener(MouseEvent.ROLL_OUT,onBarUp);
			hot_area.addEventListener(MouseEvent.MOUSE_UP,onBarUp);
			
			hot_area.addEventListener(Event.ENTER_FRAME,checkBar);
		}
		
		private function headMouseDownHandle(e:MouseEvent):void
		{
			onChangeBarPosition(1);
		}
		private function snailMouseDownHandle(e:MouseEvent):void
		{
			onChangeBarPosition(-1);
		}
		
		private function onChangeBarPosition(_d:Number):void
		{
			if(_orientation	==	NxScrollBar.VERTICAL)
			{
				if(_d<0)
				{
					//向下
					barBtn.y	=	(barBtn.y+_scrollDistance)>_extent-_barSize-_barWidth?_extent-_barSize-_barWidth:(barBtn.y+_scrollDistance);
				}else{
					//向上
					barBtn.y	=	(barBtn.y-_scrollDistance)<_barWidth?_barWidth:(barBtn.y-_scrollDistance);
				}
			}else
			{
				if(_d<0)
				{
					//向下
					barBtn.x	=	(barBtn.x+_scrollDistance)>_extent-_barSize-_barWidth?_extent-_barSize-_barWidth:(barBtn.x+_scrollDistance);
				}else{
					//向上
					barBtn.x	=	(barBtn.x-_scrollDistance)<_barWidth?_barWidth:(barBtn.x-_scrollDistance);
				}
			}
			
			checkBar(null);
		}
		
		private function checkBar(e:Event):void
		{
			dispatchEvent(new NxScrollEvent(NxScrollEvent.UPDATE_AREA,{type:_orientation,barX:barBtn.x,barY:barBtn.y,barSize:_barSize}));
		}
		
		private function drawScroll():void
		{
			first_space	=	new Sprite();//"",16,16
			last_space	=	new Sprite();
			bg_space	=	new Sprite();
			hot_area	=	new Sprite();
			_barBtn	=	new Sprite();
			barBtn.buttonMode	=	true;
			first_space.buttonMode	=	true;
			last_space.buttonMode	=	true;
			/*if(_orientation	==	ScrollBarEx.VERTICAL)
				barBtn		=	new ButtonEx("",16,1);
			else
				barBtn		=	new ButtonEx("",1,16);*/
			//barBtn.autoSize	=false
			
			addChild(bg_space);
			addChild(first_space);
			addChild(last_space);
			addChild(barBtn);
			addChild(hot_area);
			
			if(_scrollSkin==null)
			{
				//绘制背景
				DrawAPI.drawRect(bg_space.graphics,
					DrawStyle.getRectStyle(0,0,_barWidth,_barWidth),
					DrawStyle.getFillStyle(0x556B75,.2));
				if(_orientation == NxScrollBar.VERTICAL)
				{
					//绘制上箭头
					DrawAPI.drawRect(first_space.graphics,
						DrawStyle.getRectStyle(0,0,_barWidth,_barWidth),
						DrawStyle.getFillStyle(0x556B75,.5));				
					DrawAPI.DrawTriAngleBg(first_space.graphics,
						new Point(8,2),
						new Point(2,14),
						new Point(14,14),
						DrawStyle.getFillStyle(0x556B75));
					//绘制下箭头
					DrawAPI.drawRect(last_space.graphics,
						DrawStyle.getRectStyle(0,0,_barWidth,_barWidth),
						DrawStyle.getFillStyle(0x556B75,.5));
					DrawAPI.DrawTriAngleBg(last_space.graphics,
						new Point(2,2),
						new Point(14,2),
						new Point(8,14),
						DrawStyle.getFillStyle(0x556B75));
					//_extend*(_viewSize.height)/scrollView.height;
					//测试滚动条
					DrawAPI.drawRect(barBtn.graphics,
						DrawStyle.getRectStyle(0,0,_barWidth,_barSize),
						DrawStyle.getFillStyle(0x333333,.1)
					);
				}
				else
				{
					//绘制左箭头
					DrawAPI.drawRect(first_space.graphics,
						DrawStyle.getRectStyle(0,0,_barWidth,_barWidth),
						DrawStyle.getFillStyle(0x556B75,.5));				
					DrawAPI.DrawTriAngleBg(first_space.graphics,
						new Point(2,8),
						new Point(14,2),
						new Point(14,14),
						DrawStyle.getFillStyle(0x556B75));
					//绘制右箭头
					DrawAPI.drawRect(last_space.graphics,
						DrawStyle.getRectStyle(0,0,_barWidth,_barWidth),
						DrawStyle.getFillStyle(0x556B75,.5));
					DrawAPI.DrawTriAngleBg(last_space.graphics,
						new Point(2,2),
						new Point(2,14),
						new Point(14,8),
						DrawStyle.getFillStyle(0x556B75));
					
					//测试滚动条
					DrawAPI.drawRect(barBtn.graphics,
						DrawStyle.getRectStyle(0,0,_barSize,_barWidth),
						DrawStyle.getFillStyle(0x333333,.1)
					);
				}
				
				//设置位置
				//setPosition();
			}
			else
			{
				setScrollBarSkin();
			}
			setPosition();
			hot_area.alpha	=	0;
		}
		
		/**
		 * 设置滚动条各元素的大小、宽度、位置。
		 */
		private function setPosition():void
		{
			if(_orientation == NxScrollBar.VERTICAL)
			{
				barBtn.y		=	_barWidth;
//				barBtn.x 		= 	(bg_space.width - barBtn.width) * .5;
				bg_space.y		=	_barWidth;
				
				if(barSkin)
					barSkin.height	=	Math.floor(_barSize);
				else
					barBtn.height	=	Math.floor(_barSize);
				last_space.y	=	_extent - _barWidth;
				
				track.height	=	_extent-_barWidth * 2;
				
				
			}else{
				barBtn.x		=	_barWidth;
//				barBtn.y 		= 	(bg_space.height - barBtn.height) * .5;
				bg_space.x		=	_barWidth;
				if(barSkin)
					barSkin.width	=	Math.floor(_barSize);
				else
					barBtn.width	=	Math.floor(_barSize);
				last_space.x	=	_extent-_barWidth;			
				
				track.width	=	_extent-_barWidth * 2;
			}
		}
		/**
		 * 设定皮肤 
		 * 
		 */
		private function setScrollBarSkin():void
		{
			var firstSkin:SimpleButton = _scrollSkin.getChildByName("arrow1") as SimpleButton;
			if(firstSkin)
			{
				firstSkin.x	=	firstSkin.y	=	0;
				first_space.addChild(firstSkin);
			}
			
			var lastSkin:SimpleButton = _scrollSkin.getChildByName("arrow2") as SimpleButton;
			if(lastSkin)
			{
				lastSkin.x	=	lastSkin.y	=	0;
				last_space.addChild(lastSkin);
			}
			
			track = _scrollSkin.getChildByName("track") as MovieClip;
			if(track)
			{
				track.x	=	track.y	=	0;
				bg_space.addChild(track);
			}
			
			barSkin = _scrollSkin.getChildByName("thoumb") as MovieClip;
			if(barSkin)
			{
				barSkin.x	=	barSkin.y	=	0;
				barSkin.gotoAndStop( 1 );
				barBtn.addChild(barSkin);
				
				if(_orientation == NxScrollBar.VERTICAL)
				{
					barSkin.height	=	Math.floor(_barSize);
				}
				else
				{
					barSkin.width	=	Math.floor(_barSize);
				}
			}
			
			
		}
		
		public function onMouseWheel(e:MouseEvent):void
		{
			onChangeBarPosition(e.delta);
		}
		
		public function set skin(_skin:MovieClip):void
		{
			if(_scrollSkin	!= _skin )
			{
				_scrollSkin	= 	_skin;
				if(_scrollSkin	!=	null)
				{
					setScrollBarSkin();
				}				
			}
		}
		
		public function get scroll():Number
		{
			return _scroll	;
		}
		
		/**当前滑块占可滑动区的百分比，0-1内*/
		public function set scroll(val:Number):void
		{
			_scroll	=	val;
			
			if(_scroll>1)
			{
				_scroll	=	1;
			}else if(_scroll<0)
			{
				_scroll	=	0;
			}
			
			if(_orientation == NxScrollBar.HORIZONTAL)
				barBtn.x	=	_barWidth+_scroll*(bg_space.width-barBtn.width);
			else
				barBtn.y	=	_barWidth+_scroll*(bg_space.height-barBtn.height);
			checkBar(null);
		}
		
		/**设置当前滑块 的位置，同时派发一个改变显示区域的事件。
		 * @param val 百分比（0-1）
		 * 不检查_scroll范围.
		 * */
		public function setScroll(val:Number):void
		{
			_scroll	=	val;
			
			if(_orientation == NxScrollBar.HORIZONTAL)
				barBtn.x	=	_barWidth+_scroll*(bg_space.width-barBtn.width);
			else
				barBtn.y	=	_barWidth+_scroll*(bg_space.height-barBtn.height);
			checkBar(null);
		}

		public function get barBtn():Sprite
		{
			return _barBtn;
		}
		
		/**设置滑块位置，per【0,1】*/
		public function setSlider(per:Number):void
		{
			per=per>1?1:per;
			per=per<0?0:per;
			
			if(_orientation==0)
			{
				_barBtn.y = (_extent-_barWidth * 2-_barSize)*per+_barWidth;
//				barBtn.x 	= 	(bg_space.width - barBtn.width) * .5;
			}
			else
			{
				_barBtn.x = (_extent-_barWidth * 2-_barSize)*per+_barWidth;
//				barBtn.y 	= 	(bg_space.height - barBtn.height) * .5;
			}
			
			checkBar(null);
			
		}
		
		/**[只读]可滑动区域长度，单位像素*/
		public function get slideableScope():Number
		{
			return (_extent-_barWidth * 2-_barSize);
		}
		
		/** [只读]滑块当前位置占可滑动区的百分比，【0,1】，Y方向*/
		public function get sliderPerY():Number
		{
			var scrollSize:Number	=	_barBtn.y-_barWidth;
			var totalSize:Number	=	_extent-_barWidth * 2-_barSize;
			return (scrollSize < 0 ? 0 : scrollSize)/(totalSize > 0 ? totalSize : 1);
		}
		
		/** [只读]滑块当前位置占可滑动区的百分比，【0,1】，X方向*/
		public function get sliderPerX():Number
		{
			var scrollSize:Number	=	_barBtn.x-_barWidth;
			var totalSize:Number	=	_extent-_barWidth * 2-_barSize;	
			
			return (scrollSize < 0 ? 0 : scrollSize)/(totalSize > 0 ? totalSize : 1);
		}
		
		public function set scrollDistance(value:Number):void
		{
			_scrollDistance=value;
		}
		public function get scrollDistance():Number
		{
			return _scrollDistance;
		}
		
		public function get sliderMinLen():Number
		{
			return _sliderMinLen;	
		}
		
		public function set sliderMinLen(value:Number):void
		{
			_sliderMinLen=value;
			
			if(_orientation==0)
			{
				_barBtn.height=_barBtn.height<_sliderMinLen?_sliderMinLen:_barBtn.height;
				_barSize=_barBtn.height;
			}
			else if(_orientation==1)
			{
				_barBtn.width=_barBtn.width<_sliderMinLen?_sliderMinLen:_barBtn.width;
				_barSize=_barBtn.width
			}
		}

		/**滑块长度*/
		public function get barSize():int
		{
			return _barSize;
		}

		/**最少滚动值*/
		public function get minSize():Number
		{
			return _minSize;
		}

		/**
		 * @private
		 */
		public function set minSize(value:Number):void
		{
			_minSize = value;
		}


	}
}